package com.zeyu.framework.tools.console;

import com.google.common.collect.Lists;
import com.zeyu.framework.utils.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * HTTP-specific implementation of TunnelRequest.
 * Created by zeyuphoenix on 16/10/17.
 */
public class HTTPTunnelRequest extends TunnelRequest {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    /**
     * A copy of the parameters obtained from the HttpServletRequest used to
     * construct the HTTPTunnelRequest.
     */
    private final Map<String, List<String>> parameterMap =
            new HashMap<>();

    // ================================================================
    // Constructors
    // ================================================================

    /**
     * Creates a HTTPTunnelRequest which copies and exposes the parameters
     * from the given HttpServletRequest.
     *
     * @param request
     *     The HttpServletRequest to copy parameter values from.
     */
    // getParameterMap() is defined as returning Map<String, String[]>
    public HTTPTunnelRequest(HttpServletRequest request) {

        // For each parameter
        for (Map.Entry<String, String[]> mapEntry : request.getParameterMap().entrySet()) {

            // Get parameter name and corresponding values
            String parameterName = mapEntry.getKey();
            List<String> parameterValues = Arrays.asList(mapEntry.getValue());

            // Store copy of all values in our own map
            parameterMap.put(
                    parameterName,
                    new ArrayList<>(parameterValues)
            );

        }

    }

    public HTTPTunnelRequest(Map<String, Object> attributes) {
        super();
        for (Map.Entry<String, Object> attribute : attributes.entrySet()) {
            Object value = attribute.getValue();
            if (value != null) {
                if (value instanceof String) {
                    parameterMap.put(attribute.getKey(), Lists.newArrayList(value.toString()));
                } else if (value instanceof String[]) {
                    parameterMap.put(attribute.getKey(), Lists.newArrayList((String[]) value));
                } else {
                    parameterMap.put(attribute.getKey(), Lists.newArrayList(String.valueOf(value)));
                }
            }

        }
    }

    public HTTPTunnelRequest(String uri) {
        super();
        if (StringUtils.isNotBlank(uri)) {

            String[] params = StringUtils.split(uri, "&");
            for (String param : params) {
                String[] p = param.split("=");
                if (p.length == 2) {
                    Object value = p[1];
                    if (value != null) {
                        parameterMap.put(p[0], Lists.newArrayList(value.toString()));
                    }
                }
            }
        }
    }

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    @Override
    public String getParameter(String name) {
        List<String> values = getParameterValues(name);

        // Return the first value from the list if available
        if (values != null && !values.isEmpty())
            return values.get(0);

        return null;
    }

    @Override
    public List<String> getParameterValues(String name) {
        return parameterMap.get(name);
    }

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
